package com.zb.test;

import com.zb.bean.Employee1;
import org.junit.Test;

import javax.swing.text.html.Option;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Stream终止操作
 */
public class JAVA8_9_StreamAPI_终止操作 {
    List<Employee1> employees = Arrays.asList(
            new Employee1(1,"zhangsan",45, Employee1.Status.BUSY),
            new Employee1(2,"lisi",29, Employee1.Status.FREE),
            new Employee1(3,"wangwu",30, Employee1.Status.VOCATION),
            new Employee1(4,"zhaoliu",20, Employee1.Status.BUSY),
            new Employee1(6,"奥巴马",50, Employee1.Status.FREE),
            new Employee1(5,"tianqi",50, Employee1.Status.VOCATION)

    );

    /**
     * 1.查找与匹配：
     *  allMatch：检查是否匹配所有元素
     *  anyMatch: 检查是否至少匹配一个元素
     *  noneMatch: 检查是否没有匹配所有元素
     *  findFirst: 返回第一个元素
     *  findAny: 返回当前流中任意的一个元素（随机返回一个值）
     *  count: 返回流中元素的总个数
     *  max:  返回流中的最大值
     *  min: 返回流中的最小值
     */
    @Test
    public void test(){
        //allMatch
        boolean b1 = employees.stream().allMatch((e) -> e.getStatus().equals(Employee1.Status.BUSY));
        System.out.println("b1: "+b1);

        //anyMatch
        boolean b2 = employees.stream().anyMatch((e) -> e.getStatus().equals(Employee1.Status.BUSY));
        System.out.println("b2: "+b2);

        //noneMatch
        Boolean b3 = employees.stream().noneMatch((e) -> e.getStatus().equals(Employee1.Status.BUSY));
        System.out.println("b3: "+b3);

        //findFirst  (Optional用于接收可能出现空数据的返回值)
        Optional<Employee1> op1 = employees.stream().sorted((e1, e2) -> -Integer.compare(e1.getAge(),e2.getAge())).findFirst();
        System.out.println("op1: "+op1.get());

        //findAny
        //参照网址：https://zhidao.baidu.com/question/1498838916214323339.html
        Optional<Employee1> op2 = employees.stream().parallel().findAny();//parallel()并行流
        System.out.println("op2: "+op2);

        //count
        Long count = employees.stream().count();
        System.out.println("count: "+count);

        //max
        Optional<Employee1> max = employees.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
        System.out.println(max.get());

        //min
        Optional<Integer> min = employees.stream().map(e -> e.getAge()).min((x,y) -> Integer.compare(x,y));
        System.out.println("min: "+min.get());
        employees.stream().map(Employee1::getAge).min(Integer::compare);
        System.out.println("min:"+min.get());
    }

    /**
     * 2.规约
     *   reduce  可以将流中的元素反复的集合起来，得到一个新值
     */
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        Integer res1 = list.stream().reduce(0, (x, y) -> x + y);
        System.out.println("res1: " +res1);

        Optional<Integer> res2 = list.stream().reduce((x,y) -> x+y);
        System.out.println("res2: " +res2.get());

        Optional<Integer> res3 = list.stream().reduce(Integer::sum);
        System.out.println("res3: " +res3.get());
    }

    /**
     * 3.收集
     *  collect  将流转换为其他形式
     */
    @Test
    public void test2(){
       //将名字提取出来放到list集合中
        List<String> list = employees.stream().map(Employee1::getName).collect(Collectors.toList());
        System.out.println("list: " +list);

        //放置到特殊的集合中
        HashSet<String> hashSet = employees.stream().map(Employee1::getName).collect(Collectors.toCollection(HashSet::new));
        System.out.println("hashSet: " +hashSet);

        //总条数
        Long count = employees.stream().collect(Collectors.counting());
        System.out.println("count: "+count);

        //总和
        Integer sum = employees.stream().collect(Collectors.summingInt(Employee1::getAge));
        System.out.println("sum: "+sum);

        //平均值
        Double avg = employees.stream().collect(Collectors.averagingDouble(Employee1::getAge));
        System.out.println("avg: "+avg);

        //最大值
        Optional<Employee1> max = employees.stream().collect(Collectors.maxBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
        System.out.println("max: "+max.get());

        //最小值
        Optional<Integer> min = employees.stream().map(Employee1::getAge).collect(Collectors.minBy(Integer::compare));
        System.out.println("min: " +min);

        //分组
        Map<Employee1.Status, List<Employee1>> group1 = employees.stream().collect(Collectors.groupingBy(Employee1::getStatus));
        System.out.println("group1: "+group1);

        //多级分组
        Map<Employee1.Status,Map<String,List<Employee1>>> group2 = employees.stream().collect(Collectors.groupingBy(Employee1::getStatus,
                Collectors.groupingBy((Object x) ->{
            if(((Employee1)x).getAge() < 30){
                return "青年";
            }else{
                return "非青年";
            }
        })));
        System.out.println("group2: "+group2);


        //分区
        Map<Boolean, List<Employee1>> fq = employees.stream().collect(Collectors.partitioningBy(x -> x.getAge() < 30));
        System.out.println("fq: "+fq);

        //summarizingInt
        IntSummaryStatistics is = employees.stream().collect(Collectors.summarizingInt(Employee1::getAge));
        System.out.println(is.getCount());
        System.out.println(is.getSum());
        System.out.println(is.getAverage());
        System.out.println(is.getMax());
        System.out.println(is.getMin());

        //join
       String str1 = employees.stream().map(Employee1::getName).collect(Collectors.joining());
       System.out.println("str1: " +str1);
       String str2 = employees.stream().map(Employee1::getName).collect(Collectors.joining(",","--","~"));
       System.out.println("str2: " +str2);

    }
}
